#include <string>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include "hashtbl.h"
#include "EncodedStructs.h"

/* setRegisters */

int setRegisters(INSTU u, Decoded &d)
{

	/* RTYPE CASING */
	if(u.D.opcode==0)
	{
		/*rd, rt, fd*/
		if(u.R.funct==0 || u.R.funct==2 || u.R.funct==3) 
		{
			char *str=NULL;
			str=(char *)malloc(sizeof(char)*10);
			if (! str)
			{
                		printf("Out of memory! Aborting...\n");
                		exit(10);
			}

			else
			{
				setReg(u.R.rd, d->reg1);
				setReg(u.R.rt, d->reg2);
				sprintf(str, "%d", u.R.fd);
				/* printf("%s\n", str); */
				d->reg3 = str;
				return;
			}
		}

		/*rd, rt, rs*/
		else if(u.R.funct==4 || u.R.funct==6 || u.R.funct==7)
		{
			setReg(u.R.rd, d->reg1);
			setReg(u.R.rt, d->reg2);
			setReg(u.R.rs, d->reg3);
			return;
		}

		/*rd, rs*/
		else if(u.R.funct==9)
		{
			setReg(u.R.rd, d->reg1);
			setReg(u.R.rs, d->reg2);
			d->reg3 = '\0';
			return;
		}

		/*syscall, break, sync*/
		else if(u.R.funct==12 || u.R.funct==13 || u.R.funct==15)
		{
			d->reg1 = '\0';
			d->reg2 = '\0';
			d->reg3 = '\0';
			return;
			/*Not sure about sync. Can't find the format*/
		}

		/*rd, rs, rt */
		else if( (u.R.funct >=32 && u.R.funct <= 47) || u.R.funct==10 || u.R.funct==11)
		{
			setReg(u.R.rd, d->reg1);
			setReg(u.R.rs, d->reg2);
			setReg(u.R.rt, d->reg3);
			return;
		}

		/*rd*/
		else if(u.R.funct==16 || u.R.funct==18)
		{
			setReg(u.R.rd, d->reg1);
			d->reg2 = '\0';
			d->reg3 = '\0';
			return;
		}

		/*rs*/
		else if(u.R.funct==8 || u.R.funct==17 || u.R.funct==19)
		{
			setReg(u.R.rs, d->reg1);
			d->reg2 = '\0';
			d->reg3 = '\0';
			return;
		}

		/*rs, rt*/
		else if(u.R.funct==24 || u.R.funct==25 || (u.R.funct>=48 && u.R.funct<=54) )
		{
			setReg(u.R.rs, d->reg1);
			setReg(u.R.rt, d->reg2);
			d->reg3 = '\0';
			return;
		}

	}/*End of RTYPE if*/

	/*JTYPE CASES*/
	else if(u.D.opcode==2 || u.D.opcode==3)
	{
		char *target = NULL;
		target=(char *)malloc((sizeof(char)*4));
		if (! target)
        	{
                	printf("Out of memory! Aborting...\n");
                	exit(10);
        	}

		else
		{
			sprintf(target, "%d", u.J.target);
			d->reg1 = target;
			d->reg2 = '\0';
			d->reg3 = '\0';
			return;
		}
	}/*END OF JTYPE CASES*/

	/*FLOATING POINT REGISTERS*/
	
	else if(u.D.opcode == 16 || u.D.opcode == 17 || u.D.opcode == 18 || u.D.opcode == 19)
	{
        	if( (u.R.funct == 5) || (u.R.funct == 14) || (u.R.funct == 33) || (u.R.funct == 32) ||
			(u.R.funct == 36) || (u.R.funct == 15) || (u.R.funct == 6) || (u.R.funct == 7) || 
			(u.R.funct == 12) || (u.R.funct == 4) || (u.R.funct == 13) )
		{
			setFloat(u.R.fd, d -> reg1); 
			setFloat(u.R.rd, d -> reg2);
			d -> reg3 = '\0';
			return;
	        }

		else if(u.R.funct == 0 || u.R.funct == 3 || u.R.funct == 2 || u.R.funct 
		== 1)
		{
			setFloat(u.R.fd, d -> reg1);
			setFloat(u.R.rd, d -> reg2);
			setFloat(u.R.rt, d -> reg3);
			return;
		}
		else if(u.R.funct == 19 || u.R.funct == 18)
		{
			setFloat(u.R.fd, d -> reg1);
			setFloat(u.R.rd, d -> reg2);
			setReg(u.R.rt, d -> reg3);
			return;
		}
		else if(u.R.funct == 24)
		{
			d -> reg1 = '\0';
			d -> reg2 = '\0';
			d -> reg3 = '\0';
			return;
		}
	}

	/* None of the cases! */
	else
	{
		printf("Uh Oh!\n");
		return;
	}
}

